﻿namespace gui {
    using System.Collections.ObjectModel;
    using snat.model;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System;
    using System.Threading;

    /// <summary>
    /// The Messages Received List UI component of the Node Properties Tab
    /// </summary>
    public partial class MessageReceivedListView {

        public static event guiBuiltMessageListEvent BuiltMessageListEvent;
        private ObservableCollection<MessageItem> messageList;
        public ObservableCollection<MessageItem> MessageList {
            get { return messageList; }
        }

        private BaseNode nodeSelected;
        public BaseNode NodeSelected {
            get { return nodeSelected; }
        }

        public MessageReceivedListView() {
            InitializeComponent();

            // Set up messasges list for cross-thread binding
            messageList = new ObservableCollection<MessageItem>();
            DispatchingList<ObservableCollection<MessageItem>, MessageItem> dispatchingList = new DispatchingList<ObservableCollection<MessageItem>, MessageItem>(messageList, Dispatcher);
            MessageListXAML.ItemsSource = dispatchingList;

            NetworkModel.Instance.MessageProcessed += guiOnMessageSend;
            NodeListView.NodeSelectedEvent += guiOnNodeSelectionChanged;

        }

        private void addToMessageList(Message msg) {
            MessageItem m = new MessageItem(msg, nodeSelected);
            messageList.Add(m);
        }

        public void guiOnMessageSend(Message m) {
            if (nodeSelected != null) {
                foreach (BaseNode e in m.Recipients) {
                    if (e.ID == nodeSelected.ID) {
                        addToMessageList(m);
                    }
                }
            }
        }

        public void guiOnNodeSelectionChanged() {
            messageList.Clear();
            nodeSelected = NodeListView.SelectedNode;

            // Run query in another thread
            Thread thread = new Thread(() => {

                // For each received message of nodeSelected, add the message to the list
                foreach (Message m in nodeSelected.MessagesReceived) {
                    this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,
                    new Action(delegate() {
                        addToMessageList(m);
                    }));
                }

                // Notify the Total List View class
                this.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Background,
                    new Action(delegate() {
                        if (BuiltMessageListEvent != null) BuiltMessageListEvent(nodeSelected, messageList);
                    }));
            });
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }
    }
}